作者:陈广 日期:2019-6-14
做完鼠标后,我们继续来做键盘。毕竟很多人对客制化键盘感兴趣,写这么一篇文章对这些人还是很有帮助的。本文将在上一篇文章的基础上继续写代码,STM32CubeMX 操作完全一样,只是 main.c 文件里的写的鼠标代码全部删除即可。你也可以全部删除 STM32CubeMX 生成的代码,然后重新生成一遍,再按照上篇文章的《Keil配置》这一小节的内容进行操作,然后再按照本文进行操作即可。
首先打开 HID Descriptor Tool 软件,单击【File】➤【Open】,选择 keybrd.hid 文件,打开一个标准的键盘报告描述符。单击【File】➤【Save As】打开另存为窗口。在保存类型栏中选择【Header File(*.h)】项,然后将此报告保存为 keybrd.h 文件。
记事本打开新生成的 keybrd.h 文件,内容如下:
// C:\Users\cg\Desktop\keybrd.h
char ReportDescriptor[63] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x05, // USAGE_MAXIMUM (Kana)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
};
注意,长度为 63。
我们知道,STM32CubeMX 自动生成的是鼠标报告描述符,我们需要将其替换为上面生成的键盘报告描述符。打开【usbd_hid.c】文件,找到HID_MOUSE_ReportDesc
声明,将此单词中的MOUSE
更改为KEYBOARD
。然后将数组里的内容更换为上面的内容,如下图所示:
由于我们修改了数组名称,所以还要修改引用此数组的代码,代码有错误的地方很容易找到,如下图所示有波浪线的地方:
将其更改为:HID_KEYBOARD_ReportDesc
。
打开【usbd_hid.h】文件,找到:
#define HID_MOUSE_REPORT_DESC_SIZE 74U
修改为:
#define HID_KEYBOARD_REPORT_DESC_SIZE 63U
注意,这个上 63 是根据上面 HID Descriptor Tool 软件生成的 keybrd.h 里的指示得出。其实宏名称可以不改,这样省了很多事,只是为了看上去正规些才修改的。
打开【usbd_hid.c】文件,之前我们修改了宏,所有引用此宏的地方都要一起修改,查找HID_MOUSE_REPORT_DESC_SIZE
,全部替换为HID_KEYBOARD_REPORT_DESC_SIZE
,一共有 6 处。做了这么多,其实就是把报告描述符长度由 74 改为 63。
USB 设备有好几个描述符,USB HID 设备配置描述符是其中之一,我暂时没有研究它的动力,大家感兴趣的可以自行上网查找资料。
找到USBD_HID_CfgHSDesc
的声明,找到注释中的nInterfaceProtocol
项,将0x02
更改为0x01
。注释中写得很明白,2 为鼠标,1 为键盘,如下图所示:
USBD_HID_CfgHSDesc
和USBD_HID_OtherSpeedCfgDesc
中还有一样的参数(注意观察注释部分,内容和上图一样),全部更改为0x01
。
由于修改了设备配置描述符,设备的性质更改了,此时需要换一个 PID 和 VID,因为电脑才能识别。之前此开发板被认成鼠标,电脑会记住,下次再连接电脑还会认为它是鼠标。
在 Application/User 项下找到【usbd_desc.c】文件,找到下图所示代码,更改USBD_VID
和USBD_PID_FS
的值,什么值都行,跟之前不一样就行。如下图所示:
注意,以上修改了代码的文件最好做个备份,因为下次更改 STM32CubeMX 后重新生成代码会全部覆盖掉。
接下来我们编写代码,让键盘依次输出字母 a~z,键盘码为 4~29。
将之前在main()
函数中写的鼠标代码删除,更改代码如下:
/* USER CODE BEGIN 2 */
uint8_t report[8]={0};
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_Delay(5000);
int i;
for(i=4; i<=29; i++)
{
report[2] = i;
USBD_HID_SendReport(&hUsbDeviceFS,report,8);
HAL_Delay(20);
report[2] = 0;
USBD_HID_SendReport(&hUsbDeviceFS,report,8);
HAL_Delay(500);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
运行程序时,请打开记事本,确保鼠标焦点在记事本内,有 5 秒准备时间,5 秒后可以观看开发板输出情况。好,有了这些知识,大家可以着手去做一个自己的键盘了。
;